package com.billow.net.rtmp
{
	internal class RtmpPacketManage
	{
		/**
		 * 模板 
		 * @param messageID
		 * @param responseID
		 * @param amfVer
		 * @param rtmpChannel
		 * @param streamChannel
		 * @param streamTimeStamp
		 * @param params
		 * @return 
		 * 
		 */		
		private static function createInvokeMessagePacket(messageID:String
														 , responseID:uint
														   , amfVer:Boolean = false
															 , rtmpChannel:uint = 0x03
															   , streamChannel:uint = 0x00
																 , streamTimeStamp:uint = 0x00
																   , ...params:Array):RtmpPacket
		{
			var packet:RtmpPacket = new RtmpPacket();
			
			if(amfVer)
				packet.rtmpBody.writeByte(0);
			
			packet.writeObject(messageID);
			packet.writeObject(responseID);
			packet.writeObject(null);
			
			for(var i:int = 0; i < params.length; i ++)
			{
				if(amfVer)
					packet.writeObject(params[i]);
				else 
					packet.rtmpBody.writeObject(params[i]);
			}
			
			packet.rtmpChannel = rtmpChannel;
			packet.rtmpBodyType = (amfVer ? 0x11: 0x14);
			packet.streamTimeStamp = streamTimeStamp;
			packet.streamChannel = streamChannel;
			packet.rtmpBodySize = packet.rtmpBody.length;
			
			return packet;
		}
		
		
		
		/**
		 * 模板 
		 * @param messageID
		 * @param responseID
		 * @param amfVer
		 * @param rtmpChannel
		 * @param streamChannel
		 * @param streamTimeStamp
		 * @param params
		 * @return 
		 * 
		 */		
		public static function getInvokeMessagePacket(messageID:String
													   , responseID:uint
														 , amfVer:Boolean = false
														   , rtmpChannel:uint = 0x03
															 , streamChannel:uint = 0x00
															   , streamTimeStamp:uint = 0x00
																 , ...params:Array):RtmpPacket
		{
			params.unshift(streamTimeStamp);
			params.unshift(streamChannel);
			params.unshift(rtmpChannel);
			params.unshift(amfVer);
			params.unshift(responseID);
			params.unshift(messageID);
			
			return createInvokeMessagePacket.apply(null, params);
		}
		
		
		
		
		
		/**
		 * 消息包 
		 * @param messageName
		 * @param params
		 * @return 
		 * 
		 */		
		internal static function message(messageName:String, ...params:Array):RtmpPacket
		{
			params.unshift(0);
			params.unshift(0);
			params.unshift(0x03);
			params.unshift(true);
			params.unshift(0);
			params.unshift(messageName);
			
			return RtmpPacketManage.createInvokeMessagePacket.apply(null, params);
		}
		
		
		/**
		 * 连接成功包
		 * @param encoding
		 * @param responseID
		 * @return 
		 * 
		 */		
		public static function acceptConnectMessage(encoding:uint, responseID:uint):RtmpPacket
		{
			return getInvokeMessagePacket("_result", responseID, false, 0x03, 0, 0,
									{level : "status",
									code : "NetConnection.Connect.Success",
									objectEncoding : encoding,
									description : "AS_RTMP_SERVER, by SnowMan."});
		}
		
		/**
		 * 拒绝连接包
		 * @param encoding
		 * @param responseID
		 * @return 
		 * 
		 */		
		public static function rejectConnectMessage(encoding:uint, responseID:uint):RtmpPacket
		{
			return getInvokeMessagePacket("_result", responseID, false, 0x03, 0, 0,
									{level : "status",
									code : "NetConnection.Connect.Rejected",
									objectEncoding : encoding,
									description : "AS_RTMP_SERVER, by SnowMan."});
		}
		
		/**
		 * 关闭连接包
		 * @param encoding
		 * @param responseID
		 * @return 
		 * 
		 */		
		public static function closeConnectMessage(encoding:uint, responseID:uint):RtmpPacket
		{
			return getInvokeMessagePacket("_result", responseID, false, 0x03, 0, 0,
									{level : "status",
									code : "NetConnection.Connect.Closed",
									objectEncoding : encoding,
									description : "AS-RTMP-SERVER, by SnowMan."});
		}
		
		
		
		
		
		
		
		
		
		
		/** bwd */	
		public static function BWDoneMessage():RtmpPacket
		{
			return getInvokeMessagePacket("onBWDone", 0, false, 0x03, 0, 0);
		}
		
		/** createStreamMessage */			
		public static function createStreamMessage(responseID:uint, streamID:uint):RtmpPacket
		{
			return getInvokeMessagePacket("_result", responseID, false, 0x03, 0, 0, streamID);
		}
		
		/** streamPublishStartMessage */
		public static function streamPublishStartMessage(responseID:uint, streamChannel:uint):RtmpPacket
		{
			return getInvokeMessagePacket("onStatus", responseID, false, 0x08, streamChannel, 0,
				{level : "status", code : "NetStream.Publish.Start"});
		}
		
		/** streamPublishStopMessage */
		public static function streamPublishStopMessage(responseID:uint, streamChannel:uint):RtmpPacket
		{
			return getInvokeMessagePacket("onStatus", responseID, false, 0x08, streamChannel, 0,
				{level : "status", code : "NetStream.Unpublish.Success"});
		}
		
		/** streamPublishBadNameMessage */
		public static function streamPublishBadNameMessage(responseID:uint, streamChannel:uint):RtmpPacket
		{
			return getInvokeMessagePacket("onStatus", responseID, false, 0x08, streamChannel, 0,
				{level:"status", code:"NetStream.Publish.BadName"});
		}
		
		/** streamPlayResetMessage */
		public static function streamPlayResetMessage(responseID:uint, streamChannel:uint):RtmpPacket
		{
			return getInvokeMessagePacket("onStatus", responseID, false, 0x04, streamChannel, 0,
				{level : "status", code : "NetStream.Play.Reset"});
		}
		
		/** streamPlayStartMessage */
		public static function streamPlayStartMessage(responseID:uint, streamChannel:uint):RtmpPacket
		{
			return getInvokeMessagePacket("onStatus", responseID, false, 0x05, streamChannel, 0,
				{level:"status", code:"NetStream.Play.Start"});
		}
		
		/** streamPlayStopMessage */
		public static function streamPlayStopMessage(responseID:uint, streamChannel:uint):RtmpPacket
		{
			return getInvokeMessagePacket("onStatus", responseID, false, 0x05, streamChannel, 0,
				{level:"status", code:"NetStream.Play.Stop"});
		}
		
		/** streamPlayFailedMessage */
		public static function streamPlayFailedMessage(responseID:uint, streamChannel:uint):RtmpPacket
		{
			return getInvokeMessagePacket("onStatus", responseID, false, 0x08, streamChannel, 0,
				{level:"error", code:"NetStream.Play.Failed"});
		}
		
		/** streamSeekNotifyMessage */
		public static function streamSeekNotifyMessage(responseID:uint, streamChannel:uint, seekTime:uint):RtmpPacket
		{
			return getInvokeMessagePacket("onStatus", responseID, false, 0x05, streamChannel, seekTime,
				{level:"status", code:"NetStream.Seek.Notify"});
		}
		
		/** streamPauseNotifyMessage */
		public static function streamPauseNotifyMessage(responseID:uint, streamChannel:uint):RtmpPacket
		{
			return getInvokeMessagePacket("onStatus", responseID, false, 0x05, streamChannel, 0,
				{level:"status", code:"NetStream.Pause.Notify"});
		}
		
		/** streamUnpauseNotifyMessage */
		public static function streamUnpauseNotifyMessage(responseID:uint, streamChannel:uint):RtmpPacket
		{
			return getInvokeMessagePacket("onStatus", responseID, false, 0x05, streamChannel, 0,
				{level:"status", code:"NetStream.Unpause.Notify"});
		}
		
		/** streamPlayUnpublishNotifyMessage */
		public static function streamPlayUnpublishNotifyMessage(responseID:uint, streamChannel:uint):RtmpPacket
		{
			return getInvokeMessagePacket("onStatus", responseID, false, 0x08, streamChannel, 0,
				{level:"status", code:"NetStream.Play.UnpublishNotify"});
		}
	}
}